package org.fisco.bcos.evidence.client;

import org.fisco.bcos.evidence.bean.Account;
import org.fisco.bcos.evidence.contract.AccountKV;
import org.fisco.bcos.evidence.contract.ShaTest;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple5;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigInteger;

/// 工具合约 - 加密
@Service
public class ShaTestClient {
    static Logger logger = LoggerFactory.getLogger(ShaTestClient.class);

    @Autowired
    BcosConnnection bcosConnnection;

    @Value("${contract.sha_test.address}")
    protected String contractAddress;


//    /**
//     * 2. 构造合约类对象 - 部署合约
//     */
//    public void deploy() {
//        try {
//            ShaTest shaTest = ShaTest.deploy(bcosConnnection.client, bcosConnnection.cryptoKeyPair);
//            System.out.println(" deploy ShaTest success, contract address is " + shaTest.getContractAddress());
//            contractAddress = shaTest.getContractAddress();
//        } catch (Exception e) {
//            System.out.println(" deploy ShaTest contract failed, error message is  " + e.getMessage());
//        }
//    }


    /**
     * 3. 接口调用 - Keccak256 加密计算 Hash.
     * 使用合约对象调用对应的接口，处理返回结果。
     * function getKeccak256(bytes memory _memory) public returns(bytes32 result)
     */
    public String getKeccak256(String _memory) {
        try {
            ShaTest shaTest = ShaTest.load(contractAddress, bcosConnnection.client, bcosConnnection.cryptoKeyPair);
            TransactionReceipt receipt = shaTest.getKeccak256(_memory.getBytes());
            Tuple1<byte[]> retOutput = shaTest.getGetKeccak256Output(receipt);
            byte[] retByte = retOutput.getValue1();
            System.out.printf("retByte =" + retByte);
            return bytesToHexString(retByte);
            //return new String(retByte);
        } catch (Exception e) {
            logger.error(" getKeccak256 exception, error message is {}", e.getMessage());
            System.out.printf(" getKeccak256 failed, error message is %s\n", e.getMessage());
        }
        return "";
    }

    /**
     * Hex转byte[]，两种情况，Hex长度为奇数最后一个字符会被舍去
     */
    private byte[] hexTobytes(String hex) {
        if (hex.length() < 1) {
            return null;
        } else {
            byte[] result = new byte[hex.length() / 2];
            int j = 0;
            for (int i = 0; i < hex.length(); i += 2) {
                result[j++] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
            }
            return result;
        }
    }


    /**
     * Convert byte[] to hex string.这里我们可以将byte转换成int，然后利用Integer.toHexString(int)来转换成16进制字符串。
     *
     * @param src byte[] data
     * @return hex string
     */
    private String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

}


